/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package extension.room.tienlen;

import extension.room.analyse.Card;
import extension.room.analyse.CardDealer;
import extension.room.analyse.CardSet;
import java.util.LinkedList;
import java.util.List;
import log.Debug;

/**
 *
 * @author daz
 */
public class Analyser {

    public static void main(String[] args) {
        Analyser analyser = new Analyser();
        CardDealer dealer = new CardDealer();
        int numberCards = 13;
        int[] cardIds = new int[numberCards];
        dealer.shuffleCard();
        for (int i = 0; i < numberCards; i++) {
            cardIds[i] = dealer.nextCard();
        }
//        CardSet set = analyser.extractSpecialFlush(new int[]{11, 50, 25, 39});
        // CardSet set = analyser.extractSpecialPair(new int[]{32, 6});
        CardSet set = analyser.extractSpecialThreePairs(cardIds);
        Debug.d("");
        Debug.d("set :" + set.toString());
    }

    public CardSet extractSpecialThreePairs(int[] card) {
        CardSet set1 = extractSpecialFlush(card);
        if (set1 != null && set1.getSetSize() >= 3) {
            int setSize = set1.getSetSize();
            int[] cardRemainId = new int[card.length - setSize];
            int count = 0;
            for (int i = 0; i < card.length; i++) {
                boolean isDuplicate = false;
                for (int j = 0; j < setSize; j++) {
                    if (card[i] == set1.getCardId(j)) {
                        isDuplicate = true;
                        break;
                    }

                }
                if (!isDuplicate) {
                    cardRemainId[count] = card[i];
                    count++;
                }
            }
            CardSet set2 = extractSpecialFlush(cardRemainId);
            if (set2 != null && set2.getSetSize() >= 3) {
                if (set1.getSetSize() == set2.getSetSize()) {

                    if (set1.getCardId(0) % 13 == set2.getCardId(0) % 13) {
                        List<Integer> listCard = new LinkedList<Integer>();
                        for (int i = 0; i < set1.getSetSize(); i++) {
                            listCard.add(set1.getCardId(i));
                            listCard.add(set2.getCardId(i));
                        }
                        return new CardSet(listCard, CardSet.THREE_PAIR);
                    }
                } else if (set1.getSetSize() < set2.getSetSize()) {
                    int startIndex = 0;
                    for (int i = 0; i < set2.getSetSize(); i++) {
                        if (set1.getCardId(0) % 13 == set2.getCardId(i) % 13) {
                            startIndex = i;
                            break;
                        }
                    }
                    int setLength = set1.getSetSize();
                    if (set1.getCardId(setLength - 1) == set2.getCardId(startIndex + setLength - 1)) {
                        List<Integer> listCard = new LinkedList<Integer>();
                        for (int i = 0; i < set1.getSetSize(); i++) {
                            listCard.add(set1.getCardId(i));
                            listCard.add(set2.getCardId(i));
                        }
                        return new CardSet(listCard, CardSet.THREE_PAIR);
                    }

                } else if (set1.getSetSize() > set2.getSetSize()) {
                    int startIndex = 0;
                    for (int i = 0; i < set1.getSetSize(); i++) {
                        if (set2.getCardId(0) % 13 == set1.getCardId(i) % 13) {
                            startIndex = i;
                            break;
                        }
                    }
                    int setLength = set2.getSetSize();
                    if (set2.getCardId(setLength - 1) == set1.getCardId(startIndex + setLength - 1)) {
                        List<Integer> listCard = new LinkedList<Integer>();
                        for (int i = 0; i < set2.getSetSize(); i++) {
                            listCard.add(set1.getCardId(i));
                            listCard.add(set2.getCardId(i));
                        }
                        return new CardSet(listCard, CardSet.THREE_PAIR);
                    }
                }
            }
            return null;

        }
        return null;
    }

    private int getCardRank(int cardId) {
        return (cardId - 2 + 13) % 13;
    }

    public CardSet extractSpecialFlush(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (getCardRank(listCards[i]) > getCardRank(listCards[j])) {
                    swap(i, j, listCards);
                }
            }
        }
//        printListCardId(listCards);
//        Debug.d("");
//        printCard(listCards);
//        Debug.d("");
        for (int i = 0; i < numberCards; i++) {
            int step = 0;
            int numberSameValue = 0;
            int cardId = (listCards[i] - 2 + 13) % 13;
            for (int j = i + 1; j < numberCards; j++) {
                int cardRankCheck = getCardRank(listCards[j]);
                if (cardId + (j - i) - numberSameValue == cardRankCheck) {
                    step++;
                } else if (cardId + (j - i) - 1 - numberSameValue == cardRankCheck) {
                    numberSameValue++;
                } else {
                    j = numberCards;
                }
            }
//            Debug.d("day :" + step);
            if (step >= 2) {
                int[] flush = new int[step + 1];
                int rankStart = getCardRank(listCards[i]);
                int delta = 0;
                for (int k = i; k <= i + step + numberSameValue; k++) {
                    int rankNext = getCardRank(listCards[k]);
                    if (rankNext == rankStart + k - i - delta) {
                        flush[k - i - delta] = listCards[k];
//                        Debug.n(Card.getRank(listCards[k]) + Card.getSuit(listCards[k]));
                    } else if (rankNext == rankStart + k - i - 1 - delta) {
                        delta++;
                    }
                }
                return new CardSet(flush, CardSet.FLUSH);
            }
        }
        return null;
    }

    public CardSet extractFlush(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (listCards[i] / 13 > listCards[j] / 13
                        || (listCards[i] / 13 == listCards[j] / 13
                        && (listCards[i] - 2 + 13) % 13 > (listCards[j] - 2 + 13) % 13)) {
                    swap(i, j, listCards);
                }
            }
        }
        printListCardId(listCards);
        for (int i = 0; i < numberCards; i++) {
            int step = 0;
            int cardId = (listCards[i] - 2 + 13) % 13;
            for (int j = i + 1; j < numberCards; j++) {
                if (cardId + (j - i) == (listCards[j] - 2 + 13) % 13 && listCards[i] / 13 == listCards[j] / 13) {
                    step++;
                } else {
                    j = numberCards;
                }
            }
            printCard(listCards);
//            Debug.d("day :" + step);
            if (step >= 2) {
                int[] flsush = new int[step + 1];
                for (int k = i; k <= i + step; k++) {
                    flsush[k - i] = listCards[k];
//                    Debug.n(Card.getRank(listCards[k]) + Card.getSuit(listCards[k]));
                }
                return new CardSet(flsush, CardSet.FLUSH);
            }
        }
        return null;
    }

    public CardSet extractPair(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (listCards[i] % 13 > listCards[j] % 13
                        || (listCards[i] % 13 == listCards[j] % 13 && listCards[i] / 13 < listCards[j] / 13)) {
                    int temp = listCards[j];
                    listCards[j] = listCards[i];
                    listCards[i] = temp;
                }
            }
        }

        printCard(listCards);
        for (int i = 0; i < numberCards; i++) {
            int cardId = listCards[i];
            int step = 0;
            for (int j = i + 1; j < numberCards; j++) {
                if (cardId % 13 == listCards[j] % 13) {
                    step++;
                } else {
                    j = numberCards;
                }
            }
//            Debug.d("extract pair :" + step);
            if (step > 0) {
                int[] pair = new int[step + 1];
                for (int k = i; k <= i + step; k++) {
                    pair[k - i] = listCards[k];
//                    Debug.n(Card.getRank(listCards[k]) + Card.getSuit(listCards[k]));
                }
                return new CardSet(pair, CardSet.PAIR);
            }
        }
        return null;
    }

    public CardSet extractSpecialPair(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (listCards[i] % 13 > listCards[j] % 13
                        || (listCards[i] % 13 == listCards[j] % 13 && listCards[i] / 13 < listCards[j] / 13)) {
                    int temp = listCards[j];
                    listCards[j] = listCards[i];
                    listCards[i] = temp;
                }
            }
        }
//        printListCardId(listCards);
//        Debug.d("");
//        printCard(listCards);
        for (int i = 0; i < numberCards; i++) {
            int cardId = listCards[i];
            int step = 0;
            for (int j = i + 1; j < numberCards; j++) {
                if (cardId % 13 == listCards[j] % 13) {
                    step++;
                } else {
                    j = numberCards;
                }
            }
//            Debug.d("extract pair :" + step);
            if (step > 0) {
                int[] pair = new int[step + 1];
                for (int k = i; k <= i + step; k++) {
                    pair[k - i] = listCards[k];
//                    Debug.n(Card.getRank(listCards[k]) + Card.getSuit(listCards[k]));
                }
                return new CardSet(pair, CardSet.PAIR);
            }
        }
        return null;
    }

    private static void printCard(int[] listCards) {
//        for (Integer i : listCards) {
//            Debug.n(Card.getRank(i) + Card.getSuit(i));
//        }
//        System.out.println();
    }

    private static void printListCardId(int[] listCards) {
//        int numberCard = listCards.length;
//        for (int i = 0; i < numberCard; i++) {
//            System.out.print(listCards[i] + ",");
//
//        }
    }

    private static void swap(int i, int j, int[] listCards) {
        int temp = listCards[j];
        listCards[j] = listCards[i];
        listCards[i] = temp;
    }
}
